export default class ConcurrencyRequest {
  constructor({
    maxConcurrencyCount
  }) {
    this.maxConcurrencyCount = maxConcurrencyCount; // 2
    this.taskQueue = [];
    this.responses = {
      /**
       * getTest1: {
       *   result: res,
       *   error: err
       * }
       */
    };

    setTimeout(() => {
      this._doRequest();
    });
  }

  push(task) {
    this.taskQueue.push(task);
  }

  _doRequest() {
    // 没有空数组跳出
    if (!this.taskQueue.length) return; // 1
    // 当数组长度与最大并发量不同时，取最小量
    const minConcurrencyCount = _getMinCount(
      this.maxConcurrencyCount,
      this.taskQueue.length
    );
    // 根据最小量来控制最大并发量
    for (let i = 0; i < minConcurrencyCount; i++) {
      // 取出数组中的第一个，并删除
      const task = this.taskQueue.shift();
      // 最大并发量减一
      this.maxConcurrencyCount--;
      // 去执行请求
      this._runTask(task);
    }
  }

  _runTask(task) {
    task().then(res => {
      this.responses[task.name] = {
        result: res,
        error: null
      }
    }).catch(err => {
      this.responses[task.name] = {
        result: null,
        error: err
      }
    }).finally(() => {
      // 执行完成，内存空出，其他请求进入
      this.maxConcurrencyCount++;
      this._doRequest();
    })
  }
}
// 这里获取最小执行次数
function _getMinCount(count1, count2) {
  return Math.min(count1, count2);
}

// [1,2,3,4]